#include <fermat/benchmark/fermat_benchmark.h>
#include <fermat/common/atomic.h>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>

#include <fermat/ext/json/document.h>
#include <fermat/ext/json/writer.h>
#include <fermat/ext/json/stringbuffer.h>

using namespace std;
using namespace boost::property_tree;
using namespace rapidjson;


#define ROOTNAME "PEO"


struct peo_t {
    string name;
    int age;
    string banji;
};

string json_create(void)
{
    ptree pt_root;
    ptree children;
    ptree child;

    child.put("name", "xiaoming");
    child.put("age", 18);
    child.put("banji", "0302");

    children.push_back(make_pair("", child));
    pt_root.add_child(ROOTNAME, children);

    stringstream ss;
    write_json(ss, pt_root);
    return ss.str();
}

void boost_json_parse(string &s)
{
   // cout<<"========== boost_json_parse"<<endl;
    istringstream iss;
    iss.str(s);

    peo_t *peo = new peo_t;
    ptree pt_root;
    ptree children;
    ptree child;

    read_json(iss, pt_root);
    children = pt_root.get_child(ROOTNAME);
    //peo->name = children.get<string>("name");

    BOOST_FOREACH(ptree::value_type &v, children) {
        child = v.second;
        peo->name = child.get<string>("name");
        peo->age = child.get<int>("age");
        peo->banji = child.get<string>("banji");
    }

   // cout<<peo->name<<","<<peo->age<<","<<peo->banji<<endl;
}

void rapid_json_parse(string &s)
{
    //cout<<"========== rapid_json_parse"<<endl;
    peo_t *peo = new peo_t;
    Document d;
    d.Parse(s.c_str());

    Value &cnt = d[ROOTNAME];
    //cout<<cnt.IsArray()<<endl;

    for (size_t i = 0; i < cnt.Size(); ++i) {
        Value & v = cnt[i];
        peo->name = v["name"].GetString();
        peo->age = atoi(v["age"].GetString());
        peo->banji = v["banji"].GetString();
    }

   // cout<<peo->name<<","<<peo->age<<","<<peo->banji<<endl;
}


BENCHMARK(json, repaidjson, 10, 100000)
{
    string s = json_create();
    rapid_json_parse(s);
}

BENCHMARK(json, boostjson, 10, 100000)
{
    string s = json_create();
    boost_json_parse(s);
}